package middleware

import (
	"net/http"
	"strings"

	"coupons/config"

	"github.com/gin-gonic/gin"
	"github.com/golang-jwt/jwt/v4"
)

// JWTClaims JWT声明结构体
type JWTClaims struct {
	UserId string `json:"user_id"`
	jwt.RegisteredClaims
}

// JWTAuth JWT认证中间件
func JWTAuth() gin.HandlerFunc {
	return func(c *gin.Context) {
		// 从请求头获取token
		authorization := c.GetHeader("Authorization")
		if authorization == "" {
			c.JSON(http.StatusUnauthorized, gin.H{
				"code": 401,
				"msg":  "请求头中auth为空",
			})
			c.Abort()
			return
		}

		// 检查token格式
		parts := strings.SplitN(authorization, " ", 2)
		if !(len(parts) == 2 && parts[0] == "Bearer") {
			c.JSON(http.StatusUnauthorized, gin.H{
				"code": 401,
				"msg":  "请求头中auth格式有误",
			})
			c.Abort()
			return
		}

		// 解析token
		tokenString := parts[1]
		cfg := config.GetConfig()
		token, err := jwt.ParseWithClaims(tokenString, &JWTClaims{}, func(token *jwt.Token) (interface{}, error) {
			return []byte(cfg.JWT.Secret), nil
		})

		if err != nil {
			c.JSON(http.StatusUnauthorized, gin.H{
				"code": 401,
				"msg":  "token解析失败",
			})
			c.Abort()
			return
		}

		// 验证token有效性
		if claims, ok := token.Claims.(*JWTClaims); ok && token.Valid {
			// 将用户信息存储到上下文中
			c.Set("user_id", claims.UserId)
			c.Next()
		} else {
			c.JSON(http.StatusUnauthorized, gin.H{
				"code": 401,
				"msg":  "token无效",
			})
			c.Abort()
			return
		}
	}
}

// GetUserId 从上下文中获取用户Id的辅助函数
func GetUserId(c *gin.Context) (string, bool) {
	userId, exists := c.Get("user_id")
	if !exists {
		return "", false
	}
	return userId.(string), true
}
